﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MethodWorx.Core.Linq;
using MethodWorx.CMS.Content;
using System.Data.Linq;

namespace MethodWorx.CMS.Linq
{
    public class LinqContentItemRepository : LinqRepository<LinqContentItem, ContentItem>, IContentItemRepository
    {
        public LinqContentItemRepository(DataContext context) 
            : base(context)
        {
            //
            //  set this source to only return deleted items
            this.source = this.source.Where(s => s.Deleted == false);
        }

        #region IContentItemRepository Members

        public IEnumerable<ContentItem> FindByPage(Page page)
        {
            if(page == null)
                throw new ArgumentNullException("page");

            return this.source.Cast<LinqContentItem>().Where(c => c.PageId == page.Id).AsQueryable();
        }
        
        #endregion


        public IEnumerable<ContentItem> FindByTemplate(Page parentPage, string template, string orderBy, string orderDirection, int? maximum, bool preview, ContentQueryOptions options)
        {
            var query = this.source.Cast<LinqContentItem>()
               .Where(ci => ci.ProxyContentTemplate.Name == template);

            if(preview)
            {
                query = query.Where(c => c.Status == ContentStatus.Unpublished || c.Status == ContentStatus.Published);
            }
            else
            {
                query = query.Where(c => c.Status == ContentStatus.Published || c.Status == ContentStatus.PublishedAndAwaitingDelete);
            }

            switch ((orderBy ?? "").ToLower())
            {
                case "datecreated":
                    switch ((orderDirection ?? "").ToLower())
                    {
                        case "desc":
                        case "descending":
                            query = query.OrderByDescending(t => t.DateCreated);
                            break;
                        default:
                            query = query.OrderBy(t => t.DateCreated);
                            break;
                    }
                    break;
            }

            if (options == ContentQueryOptions.Descendants && parentPage != null)
            {
                //
                //  ok, we have to cycle through the results and parse some more
                query = query.ToList().Where(c => c.CountLevelsUnderPage(parentPage) >= 0).AsQueryable();
            }
            else if(options == ContentQueryOptions.DirectDescendants && parentPage != null)
            {
                query = query.ToList().Where(c => c.CountLevelsUnderPage(parentPage) == 0).AsQueryable();
            }

            if (maximum.HasValue)
                query = query.Take(maximum.Value);

            return query;
        }

    }
}
